package com.instasale.controllers;

import com.instasale.exceptions.CarIsInvalidException;
import com.instasale.models.Car;
import com.instasale.models.EngineType;
import com.instasale.services.CarService;
import com.instasale.services.FeatureService;
import com.instasale.services.SellerService;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Map;

@Controller
@RequestMapping("/cars")
public class CarsController {

    private CarService carService;
    private SellerService sellerService;
    private FeatureService featureService;

    public void setCarService(CarService carService) {
        this.carService = carService;
    }

    public void setSellerService(SellerService sellerService) {
        this.sellerService = sellerService;
    }

    public void setFeatureService(FeatureService featureService) {
        this.featureService = featureService;
    }

    @ModelAttribute("car")
    public Car getCar() {
        return new Car();
    }

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String listCars(@RequestParam(value = "sortBy", required = false) String sortBy, Model model) {
        if (sortBy == null || !carService.isColumnExists(sortBy))
            model.addAttribute(carService.listCar());
        else
            model.addAttribute(carService.listCar(sortBy));
        return "cars";
    }

    @RequestMapping(value = "{carId}", method = RequestMethod.GET)
    public String showCar(@PathVariable("carId") Integer carId, Model model) {
        Car car = carService.getById(carId);
        if (car == null)
            return "errors/404";
        model.addAttribute(carService.getById(carId));
        return "showCar";
    }

    @RequestMapping(value = "/new", method = RequestMethod.GET)
    public String newCar(Model model){
        return showBasicInformationPage(model);
    }

    @RequestMapping(value = "/basicInformation", method = RequestMethod.POST)
    public String addCar(@ModelAttribute("car") @Valid Car car, BindingResult result, Model model) {
        if(result.hasErrors()){
            return showBasicInformationPage(model);
        }
        return showFeaturesPage(model, car);
    }

    @RequestMapping(value = "/addFeatures", method = RequestMethod.POST)
    public String addFeaturesToCar(@ModelAttribute("car") @Valid Car car, BindingResult result, Model model) {
        if(result.hasErrors()){
            return showFeaturesPage(model, car);
        }
        if (!car.getUsed())
            car.setMileage(0);
        return showReviewPage(model, car);
    }

    @RequestMapping(value = "/saveCar", method = RequestMethod.POST)
    public String saveCar(@ModelAttribute("car") @Valid Car car, BindingResult result) {
        if(result.hasErrors()){
            throw new CarIsInvalidException("Car failed validation after review step.");
        }
        carService.addCar(car);
        return "redirect:/cars";
    }

    @RequestMapping(value = "{carId}/delete", method = RequestMethod.DELETE)
    public String deleteCar(@PathVariable("carId") Integer carId) {
        carService.removeCar(carId);
        return "redirect:/cars";
    }

    private String showBasicInformationPage(Model model){
        model.addAttribute("sellersList", sellerService.listSeller());
        return "catalogue/basicInformation";
    }

    private String showFeaturesPage(Model model, Car car){
        model.addAttribute("car", car);
        model.addAttribute("featuresList", featureService.listFeature());
        return "catalogue/features";
    }

    private String showReviewPage(Model model, Car car){
        model.addAttribute("car", car);
        return "catalogue/reviewCar";
    }
}
